package voldTransfo;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.uml2.uml.DataType;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.Class;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import uml2Java.IllegalVisibityException;
import uml2Java.JavaIncompatibleTypeException;
import astjava.AbstractTypeDeclaration;
import astjava.JavaFactory;

public class OldTestTransformTypesAndAttributes {
	private org.eclipse.uml2.uml.Package _umlPackage;
	
	private astjava.Package _javaPackage;
	
	private OldUML2Java _uml2Java;
	
	@Before
	public void setUp() throws Exception {
		_uml2Java = new OldUML2Java("modele_de_test/test.uml");
		_umlPackage = _uml2Java.get_UMLpackageRacine();
		_javaPackage = JavaFactory.eINSTANCE.createPackage();
		try {
			_uml2Java.transformTypes(_umlPackage, _javaPackage);
		} catch (JavaIncompatibleTypeException e) {
			e.printStackTrace();
			fail();
		} catch (IllegalVisibityException e) {
			e.printStackTrace();
			fail();
		}
	}
	
	@Test
	public void testTransformDeclarationType() {
		//-1 car on ne transforme pas les datatypes
		assertTrue(_umlPackage.getOwnedTypes().size() - 1 == _javaPackage.getOwnedElements().size());
		for (Type umlType : _umlPackage.getOwnedTypes()) {
			boolean trouve = false;
			for (astjava.AbstractTypeDeclaration javaType : _javaPackage.getOwnedElements()) {
				if (umlType instanceof DataType) 
					trouve = true;
				else if (javaType.getName().equals(umlType.getName())) 
					trouve = true;			
			}
			assertTrue(umlType.getName(), trouve);
		}
	}
	
	@Test
	public void testTransformTypePrimitiveAttribute(){
		Map<String,String> correspondance = new HashMap<String,String>();
		correspondance.put("EBoolean", "boolean");
		correspondance.put("EByte", "byte");
		correspondance.put("EChar", "char");
		correspondance.put("EDouble", "double");
		correspondance.put("EFloat", "float");
		correspondance.put("EInt", "int");
		correspondance.put("ELong", "long");
		correspondance.put("EShort", "short");
		correspondance.put("EString", "String");
		Class umlClass = (Class) _umlPackage.getOwnedType("ClassPackage");
		astjava.ClassDeclaration javaClass = null;
		for (AbstractTypeDeclaration type : _javaPackage.getOwnedElements()) {
			if (type.getName().equals("ClassPackage")) {
				javaClass = (astjava.ClassDeclaration) type;
			}
		}
		assertNotNull(umlClass);
		assertNotNull(javaClass);
		assertTrue(umlClass.getAttributes().size() == javaClass.getBodyDeclarations().size());
		for (Property umlAttribute : umlClass.getAttributes()) {
			boolean trouve = false;
			boolean typeConcordant = false;
			for (astjava.BodyDeclaration javaField : javaClass.getBodyDeclarations()) {
				if (javaField.getName().equals(umlAttribute.getName())) {
					trouve = true;
					astjava.FieldDeclaration javaFieldDeclaration = (astjava.FieldDeclaration) javaField;
					if (correspondance.get(umlAttribute.getType().getName()).equals(javaFieldDeclaration.getType().getType().getName()))
						typeConcordant = true;
				}	
			}
			assertTrue(trouve);
			assertTrue(typeConcordant);
		}
	}
	
	@Test
	public void testTransformTypeDatatypeAttribute() {
		Class umlClass = (Class) _umlPackage.getOwnedType("ClassDataType");
		astjava.ClassDeclaration javaClass = null;
		for (AbstractTypeDeclaration type : _javaPackage.getOwnedElements()) {
			if (type.getName().equals("ClassDataType")) {
				javaClass = (astjava.ClassDeclaration) type;
			}
		}
		assertNotNull(umlClass);
		assertNotNull(javaClass);
		assertTrue(umlClass.getAttributes().size() == javaClass.getBodyDeclarations().size());
		
		astjava.FieldDeclaration javaField = (astjava.FieldDeclaration) javaClass.getBodyDeclarations().get(0);
		assertEquals(umlClass.getAllAttributes().get(0).getType().getName(),javaField.getFragments().get(0).getName());
	}

	@Test
	public void testTransformAttributeInterface() {
		Interface umlInterface = (Interface) _umlPackage.getOwnedType("InterfacePublic");
		astjava.InterfaceDeclaration javaInterface = null;
		for (AbstractTypeDeclaration type : _javaPackage.getOwnedElements()) {
			if (type.getName().equals("InterfacePublic")) {
				javaInterface = (astjava.InterfaceDeclaration) type;
			}
		}
		assertNotNull(umlInterface);
		assertNotNull(javaInterface);
		assertTrue(umlInterface.getAttributes().size() == javaInterface.getBodyDeclarations().size());
		for (Property umlAttribute : umlInterface.getAttributes()) {
			boolean trouve = false;
			for (astjava.BodyDeclaration javaField : javaInterface.getBodyDeclarations()) {
				if (javaField.getName().equals(umlAttribute.getName())) {
					trouve = true;
				}	
			}
			assertTrue(trouve);
		}
	}
	
	@Test
	public void testTransformAttributeClass() {
		Class umlClass = (Class) _umlPackage.getOwnedType("ClassPublic");
		astjava.ClassDeclaration javaClass = null;
		for (AbstractTypeDeclaration type : _javaPackage.getOwnedElements()) {
			if (type.getName().equals("ClassPublic")) {
				javaClass = (astjava.ClassDeclaration) type;
			}
		}
		assertNotNull(umlClass);
		assertNotNull(javaClass);
		assertTrue(umlClass.getAttributes().size() == javaClass.getBodyDeclarations().size());
		for (Property umlAttribute : umlClass.getAttributes()) {
			boolean trouve = false;
			for (astjava.BodyDeclaration javaField : javaClass.getBodyDeclarations()) {
				if (javaField.getName().equals(umlAttribute.getName())) {
					trouve = true;
				}	
			}
			assertTrue(trouve);
		}
	}
	
	@Test
	public void testTransformLiteralEnum() {
		Enumeration umlEnum = (Enumeration) _umlPackage.getOwnedType("EnumerationPublic");
		astjava.EnumDeclaration javaEnum = null;
		for (AbstractTypeDeclaration type : _javaPackage.getOwnedElements()) {
			if (type.getName().equals("EnumerationPublic")) {
				javaEnum = (astjava.EnumDeclaration) type;
			}
		}
		assertNotNull(umlEnum);
		assertNotNull(javaEnum);
		assertTrue(umlEnum.getOwnedLiterals().size() == javaEnum.getBodyDeclarations().size());
		for (EnumerationLiteral umlLiteral : umlEnum.getOwnedLiterals()) {
			boolean trouve = false;
			for (astjava.BodyDeclaration javaLiteral : javaEnum.getBodyDeclarations()) {
				if (javaLiteral.getName().equals(umlLiteral.getName())) {
					trouve = true;
				}	
			}
			assertTrue(trouve);
		}
	}
	
	@After
	public void tearDown() throws Exception {
		_uml2Java = null;
		_umlPackage = null;
		_javaPackage = null;
	}

}
